package com.android.baseconfig.data.http.okhttp.interceptor;

import android.text.TextUtils;

import com.android.baseconfig.common.utils.Logc;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;

public class HeTLoggerInterceptor implements Interceptor {
    public static final String TAG = "OkHttpUtils";
    private String tag;
    private boolean showResponse;

    public HeTLoggerInterceptor(String tag, boolean showResponse) {
        if (TextUtils.isEmpty(tag)) {
            tag = TAG;
        }
        this.showResponse = showResponse;
        this.tag = tag;
    }

    public HeTLoggerInterceptor(String tag) {
        this(tag, false);
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        long start = System.currentTimeMillis();
        long end;
//        Logc.e(tag, "++++++++++++++++++++++++++start++++++++++++++++++++++++" + Thread.currentThread().getName());
        Request request = chain.request();
        LogcForRequest(request);
//        Logc.e(tag, getRequestUrl(request));
        Response response = chain.proceed(request);
        Response result = LogcForResponse(response, request);
        Response res = writeToHetLogsdk(result);
        end = System.currentTimeMillis();
        long time = end - start;
        if (response != null && response.code() != 200) {
            Logc.d(tag, response.code() + " " + response.message());
        }
        //Logc.e(tag, "+++++++++++++++++++++++++++end+++++++++++time consuming:" + time + "millisecond", false);
        return res;
    }


    /**
     * logsdk 记录http错误日志
     *
     * @return
     */
    private Response writeToHetLogsdk(Response response) {

        try {
            String code = String.valueOf(response.code());
            if (!(code.charAt(0) + "").equals("2") && !(code.charAt(0) + "").equals("3")) {
                String responseStr = response.toString();
                ResponseBody responseBody = response.body();
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();
                Charset charset = Charset.forName("UTF-8");
                MediaType contentType = responseBody.contentType();
                if (contentType != null) {
                    charset = contentType.charset(Charset.forName("UTF-8"));
                }
                String bodyString = buffer.clone().readString(charset);
                Logc.i("", responseStr + " ResponseBody" + bodyString);
            }

        } catch (Exception e) {
            e.printStackTrace();
            Logc.e("", e.getMessage());
        }
        return response;
    }


    private Response LogcForResponse(Response response, Request request) {
        try {
            //===>response Logc
//            Logc.e(tag, "========response'Logc=======");
            Response.Builder builder = response.newBuilder();
            Response clone = builder.build();
//            Logc.e(tag, "code : " + clone.code() + "  " + clone.request().url().host() + "  " + clone.request().url().pathSegments().get(0) + " protocol:" + clone.protocol());
//            if (!TextUtils.isEmpty(clone.message()))
//                Logc.e(tag, "message : " + clone.message());

            if (showResponse) {
                ResponseBody body = clone.body();
                if (body != null) {
                    MediaType mediaType = body.contentType();
                    if (mediaType != null) {
//                        Logc.e(tag, "responseBody's contentType : " + mediaType.toString() + " contentLength:" + body.contentLength());
                        if (isText(mediaType)) {
                            String resp = body.string();
//                            String host = request.url().toString();
//                            if (request.method().equalsIgnoreCase("post")) {
//                                if (request.body() != null && request.body() instanceof FormBody) {
//                                    FormBody requestBody = (FormBody) request.body();
//                                    host = getRequest(host, processUrl(requestBody));
//                                }
//                            }
//                            host = URLDecoder.decode(host, "utf-8");
//                            Logc.e(tag, host + "\r\n" + request.headers() + "response:" + resp);
//                            Logc.e(tag, print(resp, request));
                            body = ResponseBody.create(mediaType, resp);
                            return response.newBuilder().body(body).build();
                        } else {
                            Logc.i(tag, "responseBody's content : " + " maybe [file part] , too large too print , ignored!");
                        }
                    }
                }
            }

//            Logc.e(tag, "========response'Logc=======end");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;
    }

    public static String print(String resp, Request request) throws IOException {
        String log = getRequestUrl(request) + "\r\n" + request.headers() + "response:" + resp;
        return log;
    }

    public static String getRequestUrl(Request request) throws UnsupportedEncodingException {
        String host = request.url().toString();
        if (request.method().equalsIgnoreCase("post")) {
            if (request.body() != null && request.body() instanceof FormBody) {
                FormBody requestBody = (FormBody) request.body();
                host = getRequest(host, processUrl(requestBody));
            }
        }
        host = URLDecoder.decode(host, "utf-8");
        return host;
    }

    private static Map<String, String> processUrl(FormBody body) {
        Map<String, String> param = new HashMap<>();
        for (int i = 0; i < body.size(); i++) {
            String name = body.encodedName(i);
            String value = body.encodedValue(i);
            try {
                value = URLDecoder.decode(value, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            param.put(name, value);
        }
        return param;
    }

    private static String getRequest(String apiUrl, Map<String, String> mParam) {
        String tmp;
        StringBuilder sb = new StringBuilder();
        sb.append(apiUrl);
        sb.append("?");
        Iterator<String> it = mParam.keySet().iterator();
        while (it.hasNext()) {
            tmp = it.next();
            sb.append(tmp).append("=").append(mParam.get(tmp));
            if (it.hasNext()) {
                sb.append("&");
            }
        }
        return sb.toString();
    }

    private void LogcForRequest(Request request) {
        try {
            //Headers headers = request.headers();
            //String path = request.url().pathSegments().get(0);
//            Logc.e(tag, "========request'Logc=======");
//            Logc.e(tag, "method : " + request.method() + "  " + url + "  " + path);
//            if (headers != null && headers.size() > 0) {
//                Logc.e(tag, "headers : " + headers.toString());
//            }
//            RequestBody requestBody = request.body();
//            if (requestBody != null) {
//                MediaType mediaType = requestBody.contentType();
//                if (mediaType != null) {
//                    Logc.e(tag, "requestBody's contentType : " + mediaType.toString());
//                    if (isText(mediaType)) {
//                        Logc.e(tag, "requestBody's content : " + bodyToString(request));
//                    } else {
//                        Logc.e(tag, "requestBody's content : " + " maybe [file part] , too large too print , ignored!");
//                    }
//                }
//            }
//            Logc.e(tag, "========request'Logc=======end");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean isText(MediaType mediaType) {
        if (mediaType.type() != null && mediaType.type().equals("text")) {
            return true;
        }
        if (mediaType.subtype() != null) {
            return mediaType.subtype().equals("json") ||
                    mediaType.subtype().equals("xml") ||
                    mediaType.subtype().equals("html") ||
                    mediaType.subtype().equals("webviewhtml");
        }
        return false;
    }

    private String bodyToString(final Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "something error when show requestBody.";
        }
    }
}
